package s6_排序算法.sort6_堆排序;

import s6_排序算法.BaseSort;

import java.util.Arrays;

/**
 * <code>{@link HeapSort}</code>
 * <p>
 * description: DuiSort
 * <p>
 *
 * @author 西瓜瓜 on 2022/2/22 21:54
 *
 * 堆排序
 * 1.使用数组模拟一个顺序存储二叉树
 * 2.从最后一个非叶子节点开始（arr.length/2 - 1)，从左子节点至右子节点，从下至上进行调整， 如果子节点比当前节点大，则进行交换
 * 3.找第二个非叶子，第三个非叶子...一直找到根节点为止
 * 4.得到一个大顶堆后，将首个元素与末尾元素交换，那么最大值就到了末尾
 * 5.在开始进行大顶堆流程...
 */
public class HeapSort extends BaseSort {

    public static void main(String[] args) {
        //int[] arr = normal();
        int[] arr = {4,6,8,5,9};
        System.out.println(Arrays.toString(arr));
        new HeapSort().asc(arr);
        System.out.println(Arrays.toString(arr));
    }


    @Override
    public void asc(int[] arr) {

        System.out.println("HeapSort-------------------------------");
        long s = System.currentTimeMillis();

        heapSort(arr);

        long e = System.currentTimeMillis();
        System.out.println("HeapSort: " + (e-s) + "ms");

    }

    private void heapSort(int[] arr) {
        int temp = 0;
        for(int i=arr.length/2-1; i>=0; i--) {
            adjustHeap(arr, i, arr.length);
        }

        for(int j = arr.length-1; j>0; j--) {
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            adjustHeap(arr, 0, j);
        }
    }

    private void adjustHeap(int[] arr, int i, int len) {
        int temp = arr[i];
        for(int k = i*2+1; k<len; k=k*2+1) {
            if((k+1) < len && arr[k] < arr[k+1]) {
                k++;
            }
            if(arr[k] > temp) {
                arr[i] = arr[k];
                i=k;
            } else {
                break;
            }
        }
        arr[i] = temp;


    }

    private void heapSort2(int[] arr) {

        int len = arr.length;
        int tmp = 0;
        while(len > 1) {
            int idx = len/2 -1;
            while(idx >= 0) {
                int subLeftIdx = idx*2 + 1;
                int subRightIdx = idx*2 + 2;
                if(subLeftIdx < len && arr[subLeftIdx] > arr[idx]) {

                    if(subRightIdx < len && arr[subRightIdx] > arr[subLeftIdx]) {
                        tmp = arr[subRightIdx];
                        arr[subRightIdx] = arr[idx];
                    } else {
                        tmp = arr[subLeftIdx];
                        arr[subLeftIdx] = arr[idx];
                    }
                    arr[idx] = tmp;
                }

                idx--;
            }

            tmp = arr[0];
            arr[0] = arr[len-1];
            arr[len-1] = tmp;

            len --;
        }

    }
}
